<template>
	<div class="tz8-publish_slider" @click="quickDown">
		<div class="tz8-publish_slider_main">
			<div class="tz8-publish_slider_track" :style="{width: valuePosition}"></div>
			
			<div class="tz8-publish_slider_step" v-if="step">
				<div v-for="sd in (max + 1)" :key="sd" :style="{left: `calc(${(sd - 1) / max * 100}% - ${(sd - 1) / max * 6}px)`}"></div>
			</div>
			
			<button class="tz8-publish_slider_button" :style="{left: valuePosition}" @mousedown.prevent="down" @touchstart.prevent="down"></button>
		</div>
		
		<div class="tz8-publish_slider_marks" v-if="marks">
			<div v-for="m in formatMarks" :key="m[0]" :style="{width: `${m[2]}%`}">{{m[1]}}</div>
		</div>
	</div>
</template>

<script>
	export default {
		props: {
			value: Number,
			max: {
				type: Number,
				default: 100
			},
			step: {
				type: Boolean,
				default: false
			},
			marks: Object
		},

		data() {
			return {
				dragging: false,
				startX: 0,
				currentX: 0,
				startPosition: 0,
				newPosition: 0
			};
		},

		methods: {
			down(e) {
				this.start(e);
				window.addEventListener("mousemove", this.move);
				window.addEventListener("touchmove", this.move);
				window.addEventListener("mouseup", this.end);
				window.addEventListener("touchend", this.end);
			},
			start(e) {
				this.dragging = true;
				if (e.type === "touchstart") {
					e.clientX = e.touches[0].clientX;
				}
				this.startX = e.clientX;
				this.startPosition = parseFloat(this.valuePosition);
				this.newPosition = this.startPosition;
			},
			move(e) {
				if (this.dragging) {
					if (e.type === "touchmove") {
						e.clientX = e.touches[0].clientX;
					}
					this.currentX = e.clientX;
					if (e.target.parentNode.getBoundingClientRect) {
						const {
							width
						} = e.target.parentNode.getBoundingClientRect();
						this.newPosition = this.startPosition + ((this.currentX - this.startX) / width) * 100;
						this.setPosition(this.newPosition);
					}
				}
			},
			end(e) {
				if (this.dragging) {
					setTimeout(() => {
					  this.dragging = false;
					  this.setPosition(this.newPosition, true);
					}, 0);
					window.removeEventListener("mousemove", this.move);
					window.removeEventListener("touchmove", this.move);
					window.removeEventListener("mouseup", this.end);
					window.removeEventListener("touchend", this.end);
				}
			},
			quickDown(e) {
				const {
					clientX
				} = e;
				const {
					x,
					width
				} = e.target.parentNode.getBoundingClientRect();
				this.newPosition = ((clientX - x) / width) * 100;
				this.setPosition(this.newPosition, true);
			},
			setPosition(newPosition, isEnd = false) {
				if (newPosition === null || isNaN(newPosition)) return;
				if (newPosition < 0) {
					newPosition = 0;
				} else if (newPosition > 100) {
					newPosition = 100;
				}
				let value = parseFloat(((newPosition * this.max) / 100).toFixed(4));
				if (isEnd) {
					if (this.step) {
						value = Math.round(value);
					}
				}
				this.$emit("change", value);
			}
		},

		computed: {
			valuePosition() {
				let val = this.value;
				if (val < 0) {
					val = 0;
				} else if (val > this.max) {
					val = this.max;
				}
				return `${ (val / this.max) * 100 }%`;
			},
			
			formatMarks() {
				const entries = Object.entries(this.marks);
				entries.forEach((item, index) => {
					item[0] = Number(item[0]);
					item[2] = 100 / (entries.length - 1);
					if (index === 0 || index === entries.length - 1) {
						item[2] = item[2] / 2;
					}
				})
				return entries;
			}
		}
	};
</script>

<style>
.tz8-publish_slider {
	padding: calc(.1em + 6px) 0;
}

.tz8-publish_slider_main {
	position: relative;
	height: 6px;
	border-radius: 3px;
	background-color: #E4E7ED;
	cursor: pointer;
}

.tz8-publish_slider_track {
	height: inherit;
	background-color: #409EFF;
	border-radius: inherit;
}

.tz8-publish_slider_button {
	outline: none;
	background-color: #409EFF;
	width: 12px;
	height: 12px;
	border-radius: 10px;
	position: absolute;
	top: 50%;
	transform: translate(-50%, -50%);
	padding: 0;
	box-shadow: 0 0 4px 1px #00AAFF;
	border: none;
	cursor: pointer;
}

.tz8-publish_slider_button:hover {
	transform: translate(-50%, -50%)scale(1.1);
}

.tz8-publish_slider_step>div {
	position: absolute;
	top: 0;
	height: 6px;
	width: 6px;
	border-radius: 3px;
	background-color: #FFFFFF;
}
	
.tz8-publish_slider_marks {
	font-size: .9em;
	margin-top: .4em;
}
	
.tz8-publish_slider_marks>div {
	display: inline-block;
	text-align: center;
}
	
.tz8-publish_slider_marks>div:first-child {
	text-align: left!important;
}
	
.tz8-publish_slider_marks>div:last-child {
	text-align: right!important;
}
</style>
